import type { EventBindingConfig } from '../../../../../lib/abstract/base_destructible'
import type { ComponentStyleIdType } from '../../../../../types/interfaces'
import { BaseModule } from '../../../../../lib/abstract'
import { ICON_IDS } from '../../../../../lib/icons/types/constants'
import { ToolKit } from '../../../../../lib/utils/toolkit'
import {
  AppStyleCollections,
  ComponentStyleId,
  getCurrentHostname,
  logger,
  MODULE_CONFIG,
  PROJECT_PREFIX,
} from '../../../../../types/constants'
import { ConfigManager } from '../../../../config_manager'
import { StyleManager } from '../../../../style_manager'

interface Config {
  enabled?: boolean
  iconCollapsed?: boolean
}

export class GreasyForkSearchNavigator extends BaseModule {
  readonly id: string = 'greasy_fork_search_navigator'
  readonly styleId: string = ComponentStyleId[this.name]
  isInitialized: boolean = false
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)
  private static instance: GreasyForkSearchNavigator

  // 图标相关配置
  private readonly ICON_SIZE = 32
  private readonly COLLAPSED_SIZE = 16
  private readonly ICON_MARGIN = 16
  private readonly ANIMATION_DURATION = 300

  private $container: JQuery<HTMLElement> | null = null
  private $mainIcon: JQuery<HTMLElement> | null = null
  private $toggleArrow: JQuery<HTMLElement> | null = null

  config: Config = {
    enabled: true,
    iconCollapsed: false,
  }

  get name(): ComponentStyleIdType {
    return 'GreasyForkSearchNavigator'
  }

  get eventConfigs(): EventBindingConfig[] {
    return [
      // 油叉图标点击事件
      {
        selector: this.$mainIcon || $(),
        eventType: 'click',
        handler: () => this.navigatorToSearchPage(),
        meta: { category: 'icon' },
      },
      // 方向箭头点击事件
      {
        selector: this.$toggleArrow || $(),
        eventType: 'click',
        handler: () => this.toggleIconState(),
        meta: { category: 'arrow' },
      },
    ]
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): GreasyForkSearchNavigator {
    if (!GreasyForkSearchNavigator.instance) {
      GreasyForkSearchNavigator.instance = new GreasyForkSearchNavigator()
    }
    return GreasyForkSearchNavigator.instance
  }

  handleCleanupReferences(): void {
    this.$container?.remove()
    this.$container = null
    this.$mainIcon = null
    this.$toggleArrow = null
  }

  handleCleanupOthers(): void {
    // 清除动画
    this.$container?.stop(true, true)
  }

  core(): void {
    this.loadConfig()

    if (!this.config.enabled)
      return

    this.createFloatingIcon()
    // 注册样式
    StyleManager.getInstance().registerStyle(this.styleId, this.getStyles(), false, true)
  }

  private createFloatingIcon(): void {
    // 创建容器
    this.$container = $(`
      <div class="${PROJECT_PREFIX}-gf-navigator-container">
        <div class="gf-main-icon" >
            <img src="${this.iconService.api.icon.asDataUrl(ICON_IDS.platform.greasyFork)}" alt="Greasy Fork Icon">
        </div>
        <div class="gf-toggle-arrow">
            <img src="${this.iconService.api.icon.asDataUrl(ICON_IDS.action.fold)}" alt="Toggle Arrow">
        </div>
      </div>
    `).appendTo('body')

    this.$mainIcon = this.$container.find('.gf-main-icon')
    this.$toggleArrow = this.$container.find('.gf-toggle-arrow')

    this.autoBindEvents()

    // 初始状态
    if (this.config.iconCollapsed) {
      this.collapseIcon()
    }

    // 标记为项目元素
    ToolKit.browser.platform.markProjectElement(this.$container)
  }

  private toggleIconState(): void {
    this.config.iconCollapsed = !this.config.iconCollapsed
    this.applyConfig({ iconCollapsed: this.config.iconCollapsed })
  }

  private collapseIcon(): void {
    this.$container?.animate({
      right: `-4px`,
    }, this.ANIMATION_DURATION)

    this.$mainIcon?.addClass(AppStyleCollections.Hide.ELEMENT)
    this.$toggleArrow?.css('transform', 'rotate(0deg)')
  }

  private expandIcon(): void {
    this.$container?.animate({
      right: `${this.ICON_MARGIN}px`,
    }, this.ANIMATION_DURATION)

    this.$mainIcon?.removeClass(AppStyleCollections.Hide.ELEMENT)
    this.$toggleArrow?.css('transform', 'rotate(-180deg)')
  }

  onToggleCallback(_id: string, checked: boolean): void {
    super.onToggleCallback(_id, checked)
  }

  /**
   * 跳转到油猴脚本搜索页面
   */
  navigatorToSearchPage(): void {
    // 移除www.前缀
    const cleanHostname = getCurrentHostname().replace(/^www\./i, '')
    const url = `${MODULE_CONFIG.URL.greasyFork.searchBySiteUrl.replace('%s', cleanHostname)}`
    ToolKit.browser.url.openNewTab(url)
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    if (config.iconCollapsed !== undefined && this.$container) {
      if (config.iconCollapsed) {
        this.collapseIcon()
      }
      else {
        this.expandIcon()
      }
    }

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  getStyles(): string {
    return `
.${PROJECT_PREFIX}-gf-navigator-container {
  position: fixed; 
  right: ${this.ICON_MARGIN}px; 
  top: 50%; 
  transform: translateY(-50%);
  z-index: 99999;
  display: flex;
  flex-direction: column;
  align-items: center;
  
  .gf-main-icon {
    width: ${this.ICON_SIZE}px; 
    height: ${this.ICON_SIZE}px;
    
    img {
      width: 100%;
      height: 100%;
    }
  }
  
  .gf-toggle-arrow {
    margin-top: 5px;
    cursor: pointer;
    width: ${this.COLLAPSED_SIZE}px; 
    height: ${this.COLLAPSED_SIZE}px;
    
    img {
      width: 100%;
      height: 100%;
    }
  }
}
`
  }
}
